<?php
declare (strict_types=1);

namespace app\install\controller;

use app\BaseController;
use think\exception\HttpResponseException;
use think\facade\View;
use think\response\Json;

class Index extends BaseController
{
    private $_installBusiness;
    private const _CONFIRM_PASSWORD_ERROR_MESSAGE                   = '管理员两次密码不一致，请检查';
    private const _EMAIL_ERROR_MESSAGE                              = '请输入正确的邮箱';
    private const _PHONE_ERROR_MESSAGE                              = '请输入正确的手机';
    private const _CHECK_RUN_ENVIRONMENT_AND_DIR_PERMISSION_MESSAGE = '请检查运行环境、目录权限';
    private const _INSTALLED_FAILED_MESSAGE                         = '安装失败';
    private const _INSTALLED_SUCCESS_MESSAGE                        = '安装成功';
    private const _SUCCESS_MESSAGE                                  = 'success';

    public function initialize()
    {
        parent::initialize();
        $noAuth = !strstr($this->request->pathinfo(), "success");
        if (file_exists('../install.lock') && $noAuth) {
            return $this->redirect((string)url('platform/login/index'));
        }

        $this->_installBusiness = new \app\install\business\Install();
    }

    public function redirect(...$args)
    {
        throw new HttpResponseException(redirect(...$args));
    }

    public function index(): string
    {
        $dirs = $this->_installBusiness->getDirs();
        View::assign(['dirs' => $dirs]);

        $extensions = $this->_installBusiness->getExtensions();
        View::assign(['extensions' => $extensions]);
        return View::fetch();
    }

    public function checkDirsAndEnvironment(): Json
    {
        if (!$this->request->isPost()) {
            return show(config(self::_CONFIG_STATUS_ERROR_CODE), self::_REQUEST_WAY_ERROR_MESSAGE);
        }

        $dirs            = $this->_installBusiness->getDirs();
        $checkDirs       = $this->_installBusiness->checkDirs($dirs);
        $extensions      = $this->_installBusiness->getExtensions();
        $checkExtensions = $this->_installBusiness->checkExtensions($extensions);
        if (!$checkDirs || !$checkExtensions) {
            return show(config(self::_CONFIG_STATUS_ERROR_CODE), self::_CHECK_RUN_ENVIRONMENT_AND_DIR_PERMISSION_MESSAGE);
        }

        return show(config(self::_CONFIG_STATUS_SUCCESS_CODE), self::_SUCCESS_MESSAGE);
    }

    public function setting(): string
    {
        return View::fetch();
    }

    public function doInstall(): Json
    {
        if (!$this->request->isPost()) {
            return show(config(self::_CONFIG_STATUS_ERROR_CODE), self::_REQUEST_WAY_ERROR_MESSAGE);
        }

        $dirs            = $this->_installBusiness->getDirs();
        $checkDirs       = $this->_installBusiness->checkDirs($dirs);
        $extensions      = $this->_installBusiness->getExtensions();
        $checkExtensions = $this->_installBusiness->checkExtensions($extensions);
        if (!$checkDirs || !$checkExtensions) {
            return show(config(self::_CONFIG_STATUS_ERROR_CODE), self::_CHECK_RUN_ENVIRONMENT_AND_DIR_PERMISSION_MESSAGE);
        }

        $data['dbHost']           = $this->request->param('db_host', '', 'trim');
        $data['dbUser']           = $this->request->param('db_user', '', 'trim');
        $data['dbPass']           = $this->request->param('db_pass', '', 'trim');
        $data['dbName']           = $this->request->param('db_name', '', 'trim');
        $data['dbPort']           = $this->request->param('db_port', '3306', 'intval');
        $data['username']         = $this->request->param('username', '', 'trim');
        $data['phone']            = $this->request->param('phone', '', 'trim');
        $data['email']            = $this->request->param('email', '', 'trim');
        $data['password']         = $this->request->param('password', '', 'trim');
        $data['confirm_password'] = $this->request->param('confirm_password', '', 'trim');

        if ($data['password'] !== $data['confirm_password']) {
            return show(config(self::_CONFIG_STATUS_ERROR_CODE), self::_CONFIRM_PASSWORD_ERROR_MESSAGE);
        }

        if (!filter_var($data['email'], FILTER_VALIDATE_EMAIL)) {
            return show(config(self::_CONFIG_STATUS_ERROR_CODE), self::_EMAIL_ERROR_MESSAGE);
        }

        if (!preg_match('/^1\d{10}$/', $data['phone'])) {
            return show(config(self::_CONFIG_STATUS_ERROR_CODE), self::_PHONE_ERROR_MESSAGE);
        }

        $res = $this->_installBusiness->checkDb($data);
        if (!$res['result']) {
            return show(config(self::_CONFIG_STATUS_ERROR_CODE), $res['message']);
        }

        $installRes = $this->_installBusiness->install($data);
        if (!$installRes) {
            return show(config(self::_CONFIG_STATUS_ERROR_CODE), self::_INSTALLED_FAILED_MESSAGE);
        }

        return show(config(self::_CONFIG_STATUS_SUCCESS_CODE), self::_SUCCESS_MESSAGE);
    }

    public function success(): string
    {
        $installFlag = $this->_installBusiness->checkInstalled();
        View::assign([
            'installFlag' => $installFlag,
            'msg'         => $installFlag ? self::_INSTALLED_SUCCESS_MESSAGE : self::_INSTALLED_FAILED_MESSAGE,
        ]);
        return View::fetch();
    }
}
